package com.zhihuishu.micro.course.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicLong;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.apache.ibatis.session.RowBounds;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.Pipeline;

import com.able.openapi.zhsCourse.IOnlineSchoolForZhsCourseService;
import com.github.abel533.entity.Example;
import com.github.abel533.entity.Example.Criteria;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.zhihuishu.micro.course.constant.CourseTypeEnum;
import com.zhihuishu.micro.course.dao.AssistantsMapper;
import com.zhihuishu.micro.course.dao.CcCourseMapper;
import com.zhihuishu.micro.course.dao.CourseBuildMapper;
import com.zhihuishu.micro.course.dao.FirstStepStatMapper;
import com.zhihuishu.micro.course.dao.TblCourseMapper;
import com.zhihuishu.micro.course.dto.CourseBaseInfoDto;
import com.zhihuishu.micro.course.dto.CourseCategoryDto;
import com.zhihuishu.micro.course.dto.CourseDto;
import com.zhihuishu.micro.course.dto.CourseExtendDto;
import com.zhihuishu.micro.course.dto.ScoreAssessRuleDto;
import com.zhihuishu.micro.course.helper.LogModule;
import com.zhihuishu.micro.course.helper.RedisKeyHelper;
import com.zhihuishu.micro.course.helper.RemoteLogHelper;
import com.zhihuishu.micro.course.model.Assistants;
import com.zhihuishu.micro.course.model.CcCourse;
import com.zhihuishu.micro.course.model.CourseBuild;
import com.zhihuishu.micro.course.model.CourseStatus;
import com.zhihuishu.micro.course.model.FirstStepStat;
import com.zhihuishu.micro.course.model.MeetCourse;
import com.zhihuishu.micro.course.model.ScoreAssessRule;
import com.zhihuishu.micro.course.model.TblCourse;
import com.zhihuishu.micro.course.service.CategoryService;
import com.zhihuishu.micro.course.service.ChapterService;
import com.zhihuishu.micro.course.service.CourseBuildService;
import com.zhihuishu.micro.course.service.CourseExtendService;
import com.zhihuishu.micro.course.service.CourseFolderService;
import com.zhihuishu.micro.course.service.CourseService;
import com.zhihuishu.micro.course.service.LessonService;
import com.zhihuishu.micro.course.service.LessonVideoService;
import com.zhihuishu.toolkit.helper.BeanHelper;
import com.zhihuishu.toolkit.jedis.JedisHelper;
import com.zhihuishu.toolkit.jedis.JedisHelper.Handler;
import com.zhihuishu.toolkit.jedis.template.JedisExecutor;

import aj.org.objectweb.asm.Handle;

@Service("courseService")
public class CourseServiceImpl extends BaseService implements CourseService {
    
    /**
     * 在线式
     */
    private final Integer ONLINE_MODEL=2;
    /**
     * 混合式
     */
    private final Integer MIX_MODEL=1;
    /**
     * 完整
     */
    private final Integer COMPLETE=1;
    /**
     * 不完整
     */
    private final Integer INCOMPLETE=0;
    /**
     * 建课第一步
     */
    private final Integer COURSE_FIRST_STEP=1;
    
    

    @Resource
    private CcCourseMapper ccCourseMapper;

    @Resource
    private JedisExecutor jedisExecutor;

    @Resource
    private TblCourseMapper tblCourseMapper;

    @Resource
    private CategoryService categoryService;

    @Resource
    private CourseExtendService courseExtendService;

    @Resource
    private ChapterService chapterService;

    @Resource
    private LessonService lessonService;

    @Resource
    private LessonVideoService lessonVideoService;

    @Resource
    private CourseFolderService courseFolderService;// 课程资料

    @Resource
    private FirstStepStatMapper firstStepStatMapper;// 建课第一步六小步状态

    @Resource
    private CourseBuildMapper courseBuildMapper;// 保存新版建课的状态
    @Resource
    private CourseBuildService courseBuildService;

    @Resource
    private AssistantsMapper assistantsMapper;
    

    @Resource
    private IOnlineSchoolForZhsCourseService onlineSchoolForZhsCourseService;
    
    
    
    
    

    @Override
    public CourseDto createOverSeasCourse(String courseName, long createUser) {// 海外建课项目创建课程
        // TODO Auto-generated method stub
        CourseDto courseDto = create(null, courseName, createUser, CourseTypeEnum.overSeasCourse.getCode());
        // 往权限表插入 创建课程负责人数据
        saveAssistants(createUser, courseDto.getCourseId());

        onlineSchoolForZhsCourseService.clearUserAuthorityCache(createUser);// 清除用户缓存

        // 存缓存
        this.setRedisCourseData(courseDto.getCourseId());

        // 新增缓存set列表
        this.addSetRedisCourseIds(courseDto.getCourseId().toString(), createUser);

        return courseDto;
    }

    @Override
    public CourseDto create(String courseName, long createUser) {// CC创建课程
        CourseDto courseDto = this
                .create(null, courseName, createUser, CourseTypeEnum.shareCourese.getCode());
        // 往权限表插入 创建课程负责人数据
        saveAssistants(createUser, courseDto.getCourseId());
        return courseDto;

    }

    private void saveCourseAddInfo(long userId, long courseId, long ccCourseId, Integer courseTypeCode) {
        // 为课程创建默认的资料顶级文件夹
        courseFolderService.saveDefaultCourseFolder(userId, courseId, ccCourseId);

        if (courseTypeCode.equals(CourseTypeEnum.shareCourese.getCode())) {// 创建的是共享课
            // 保存新版建课第一步的六小步状态
            firstStepStatMapper.saveCourseFirstStepStat(courseId);
            // 保存建课状态
            courseBuildMapper.saveCourseBuildStatus(courseId);
        }

    }

    // 保存助教信息
    private void saveAssistants(long createUser, Long courseId) {
        Assistants assistants = new Assistants();
        assistants.setCourseId(courseId);
        assistants.setUserId(createUser);
        assistants.setType(3);// 创建人 课程负责人
        assistantsMapper.save(assistants);
    }

    @Override
    public CourseDto create(Long myuniCourseId, String courseName, long createUser, Integer courseTypeCode) {// myuni创建课程
        RemoteLogHelper.log(LogModule.COURSE_SAVE.getCode(), createUser, "[开始]创建课程[{}]", courseName);
        CourseDto course = new CourseDto();
        // 创建CC_COURSE数据
        CcCourse ccCourse = new CcCourse();
        ccCourse.setLimitDay(7);// 期末考试默认为7天
        ccCourseMapper.save(ccCourse);
        Long ccCourseId = ccCourse.getId();
        if (ccCourseId == null)
            throw new RuntimeException("创建CC_COURSE记录失败!");
        course.setLinkCourseId(ccCourseId);
        // 创建TBL_COURSE数据
        TblCourse tblCourse = new TblCourse();
        tblCourse.setLinkCourseId(ccCourseId);
        if (myuniCourseId != null){
        	tblCourse.setMyuniCourseId(myuniCourseId);
        	tblCourse.setCourseOpener(2);
        }
        tblCourse.setName(courseName);
        if (courseTypeCode.equals(CourseTypeEnum.minCourse.getCode())
                || courseTypeCode.equals(CourseTypeEnum.shareCourese.getCode())
                || courseTypeCode.equals(CourseTypeEnum.overSeasCourse.getCode())) {// 微课程 共享课 海外课程
            tblCourse.setType(courseTypeCode);// 课程类型
            tblCourse.setTurnType(0);// 私有云类型
        }

        if (courseTypeCode.equals(CourseTypeEnum.privateCourse.getCode())) {// 私有云课程
            tblCourse.setType(1);// 课程类型
            tblCourse.setTurnType(1);// 私有云类型
        }

        tblCourse.setMajorSpeaker(createUser); // 初始课程负责人指定为创建人
        tblCourse.setCreatePerson(createUser);
        tblCourseMapper.save(tblCourse);
        saveCourseAddInfo(createUser, tblCourse.getCourseId(), ccCourseId, courseTypeCode);
        if (tblCourse.getCourseId() == null)
            throw new RuntimeException("创建TBL_COURSE记录失败!");
        course.setCourseId(tblCourse.getCourseId());
        RemoteLogHelper.log(LogModule.COURSE_SAVE.getCode(), createUser, "[完成]创建课程[{}]({})", courseName,
                course.getCourseId());
        return course;
    }

    @Override
    public CourseDto get(final long courseId) {
        final CourseDto target = new CourseDto();
        jedisExecutor.execute( new Handler() {
            @Override
            public void handle(Jedis jedis) {
                CourseDto dto = null;
                String key = RedisKeyHelper.courseKey(courseId);
                if (!jedis.exists(key)) {
                    // 如果Key不存在，Touch缓存
                    dto = touchCourse(courseId);
                } else {
                    // 如果Key存在，将信息转换为课程DTO
                    Map<String, String> map = jedis.hgetAll(key);
                    if (!CollectionUtils.isEmpty(map) && map.get("courseId") != null) {
                        dto = BeanHelper.transTo(map, CourseDto.class);
                    }
                }
                if (dto != null && dto.getCourseId() != null) {
                    BeanHelper.copyProperties(dto, target);
                }
            }
        });
        return target.getCourseId() != null ? target : null;
    }

    /**
     * 从数据库中查询课程数据
     * 
     * @param courseId
     * @return
     */
    private CourseDto getFromDb(long courseId) {
        // 查询TBL_COURSE
        TblCourse tblCourse = tblCourseMapper.get(courseId);
        if (tblCourse == null || tblCourse.getLinkCourseId() == null)
            return null;
        // 查询CC_COURSE
        CcCourse ccCourse = ccCourseMapper.get(tblCourse.getLinkCourseId());
        // 查询COURSE_EXTEND_PROP
        CourseExtendDto extCourse = courseExtendService.get(courseId);
        // 组装数据
        CourseDto course = new CourseDto();
        if (tblCourse != null)
            fillCourse(course, tblCourse);
        if (ccCourse != null)
            fillCourse(course, ccCourse);
        if (extCourse != null)
            fillCourse(course, extCourse);
        course.setCourseId(courseId);
        return course;
    }

    /**
     * 使用TblCourse填充CourseDto
     * 
     * @param target
     * @param origin
     */
    private void fillCourse(final CourseDto target, final TblCourse origin) {
        if (origin == null)
            return;
        target.setCourseId(origin.getCourseId());
        target.setName(origin.getName());
        target.setChapterUnit(origin.getChapterUnit());
        target.setImg(origin.getImg());
        target.setIntroduction(origin.getIntroduction());
        target.setCourseMode(origin.getCourseMode());
        target.setCourseOpener(origin.getCourseOpener());
        target.setCreateTime(origin.getCreateTime());
        target.setCreator(origin.getCreatePerson());
        target.setLinkCourseId(origin.getLinkCourseId());
        target.setMeetCourseState(origin.getMeetCourseState());
        target.setSchoolId(origin.getSchoolId());
        target.setSchoolName(origin.getSchoolName());
        target.setState(origin.getState()==null?-1:origin.getState());//建课进度状态 如果为空 则设置为-1
        target.setType(origin.getType());
        target.setUserId(origin.getMajorSpeaker());
        target.setUserName(origin.getTeacherName());
        target.setCourseCategory(origin.getCourseCategory());
        target.setCredit(origin.getCredit());
        target.setPeriod(origin.getCourseTime());// 总学时
        
        // target.setOnlineCoursePeriod(origin.getCourseTime());//在线学时
        // target.setMeetCoursePeriod(origin.getMeetCourseTime());//见面课学时
        /*
         * if (target.getOnlineCoursePeriod()==null) { target.setOnlineCoursePeriod(0); } if
         * (target.getMeetCoursePeriod()==null) { target.setMeetCoursePeriod(0);//见面课学时 }
         */
        // target.setPeriod(target.getOnlineCoursePeriod()+target.getMeetCoursePeriod());//总学时
        target.setTurnType(origin.getTurnType());
        if (origin.getMyuniCourseId() != null) {// 存在myuniCourseId 则添加进缓存
            target.setMyuniCourseId(origin.getMyuniCourseId());
        }
    }

    /**
     * 使用CcCourse填充CourseDto
     * 
     * @param target
     * @param origin
     */
    private void fillCourse(final CourseDto target, final CcCourse origin) {
        if (origin == null)
            return;
        target.setIsJumpChapter(origin.getIsJumpChapter());
        target.setLimitDay(origin.getLimitDay());
        target.setStudyHour(origin.getStudyHour());
        target.setReleaseStatus(origin.getReleaseStatus());
        target.setTags(origin.getCourseTag());
        target.setVideoId(origin.getVideoId());
        target.setMovieClips(origin.getMovieClips());
        target.setMovieClipsImg(origin.getMovieClipsImg());
        target.setCreateStep(origin.getCreateStep());//建课步骤
    }

    /**
     * 使用CourseExtendDto填充CourseDto
     * 
     * @param target
     * @param origin
     */
    private void fillCourse(final CourseDto target, final CourseExtendDto origin) {
        BeanHelper.copyProperties(origin, target);
    }

    @Override
    public void remove(long courseId, long deleteUser) {
        RemoteLogHelper.log(LogModule.COURSE_REMOVE.getCode(), deleteUser, "[开始]删除课程({})", courseId);
        // 查出CC_COURSE_ID
        Long linkCourseId = this.getLinkCourseId(courseId);
        // 数据库中删除课程数据
        if (linkCourseId != null) {
            ccCourseMapper.remove(linkCourseId);
        }
        tblCourseMapper.remove(courseId, deleteUser);
        // 清除课程缓存
        removeCache(courseId);
        RemoteLogHelper.log(LogModule.COURSE_REMOVE.getCode(), deleteUser, "[完成]删除课程({})", courseId);
        // 删除缓存
        this.removeCourseDtoCache(courseId);
        this.removeCacheCourseDtoKeys(deleteUser, String.valueOf(courseId));
        onlineSchoolForZhsCourseService.deleteAssistantsByCourseId(courseId);//删除助教

    }

    @Override
    public void update(CourseDto course, long updateUser) {
        Assert.notNull(course, "更新课程对象不能为!");
        Assert.notNull(course.getCourseId(), "更新课程ID不能为空!");

        RemoteLogHelper.log(LogModule.COURSE_UPDATE.getCode(), updateUser, "[开始]更新课程({})",
                course.getCourseId());

        // XXX 计数设计是为了避免非必要的数据库操作
        // 更新TBL_COURSE
        TblCourse tblCourse = new TblCourse();
        int fillTblCourseCount = fillTblCourse(course, tblCourse);
        if (fillTblCourseCount > 0) { // 变更字段数大于0才执行更新
            if (tblCourse != null && tblCourse.getCourseId() != null) {
                tblCourseMapper.update(tblCourse);
                RemoteLogHelper.log(LogModule.COURSE_UPDATE.getCode(), updateUser, "[完成]更新TBL_COURSE表数据({})",
                        course.getCourseId());
            }
        }

        // 更新CC_COURSE
        CcCourse ccCourse = new CcCourse();
        int fillCcCourseCount = fillCcCourse(course, ccCourse);
        if (fillCcCourseCount > 0) { // 变更字段数大于0才执行更新
            ccCourse.setId(this.getLinkCourseId(course.getCourseId()));
            if (ccCourse.getId() != null) {
                ccCourseMapper.update(ccCourse);
                RemoteLogHelper.log(LogModule.COURSE_UPDATE.getCode(), updateUser,
                        "[完成]更新CC_COURSE表数据({}/{})", ccCourse.getId(), course.getCourseId());
            }
        }

        // 更新COURSE_EXTEND_PROP
        CourseExtendDto extCourse = new CourseExtendDto();
        int fillCourseExtendCount = fillExtCourse(course, extCourse);
        if (fillCourseExtendCount > 0) {
            courseExtendService.update(course.getCourseId(), extCourse);
            RemoteLogHelper.log(LogModule.COURSE_UPDATE.getCode(), updateUser,
                    "[完成]更新COURSE_EXTEND_PROP表数据({})", course.getCourseId());
        }

        // 更新完成后，Touch缓存
        touchCourse(course.getCourseId());

        // 当更新操作 课程类型为海外并且本次修改了名称 删除缓存然后新增
        if (course.getType() == CourseTypeEnum.overSeasCourse.getCode() && course.getName() != null) {
            this.removeCourseDtoCache(course.getCourseId());
            this.setRedisCourseData(course.getCourseId());
        }
    }

    /**
     * 清除课程缓存
     * 
     * @param courseId
     * @return
     */
    private void removeCache(final long courseId) {
        jedisExecutor.execute( new Handler() {
            @Override
            public void handle(Jedis jedis) {
                jedis.del(RedisKeyHelper.courseKey(courseId));
            }
        });
    }

    /**
     * 填充CourseExtend数据，返回非空填充数
     * 
     * @param course
     * @param extCourse
     * @return
     */
    private int fillExtCourse(CourseDto course, CourseExtendDto extCourse) {
        int count = 0;
        if (course.getCourseBackground() != null)
            count++;
        if (course.getCourseTarget() != null)
            count++;
        if (course.getCoursePopularizeType() != null)
            count++;
        if (course.getCoursePopularizeContent() != null)
            count++;
        if (course.getInstitute() != null)
            count++;
        if (course.getCourseTeacher() != null)
            count++;
        if (course.getCourseTeacherEmail() != null)
            count++;
        if (course.getCourseTeacherMobile() != null)
            count++;
        if (course.getCourseTeacherLevel() != null)
            count++;
        if (course.getCourseAssistants() != null)
            count++;
        if (course.getCourseAssistantsContact() != null)
            count++;
        if (course.getMeetCoursePeriod() != null)
            count++;
        if (course.getOnlineCoursePeriod() != null)
            count++;
        if (course.getLearningMethods() != null)
            count++;
        if (course.getLearningOutcomes() != null)
            count++;
        if (course.getCourseRunningTerm() != null)
            count++;
        if (course.getCourseRecruitObjs() != null)
            count++;
        if (course.getCourseAcademicPrepare() != null)
            count++;
        if (course.getCourseVideoType() != null)
            count++;
        if (count > 0) {
            BeanHelper.copyProperties(course, extCourse);
        }
        return count;
    }

    /**
     * 填充TblCourse数据，返回非空填充数
     * 
     * @param course
     * @param tblCourse
     * @return
     */
    private int fillTblCourse(final CourseDto course, final TblCourse tblCourse) {
        int count = 0;
        tblCourse.setCourseId(course.getCourseId());
        if (course.getName() != null) {
            tblCourse.setName(course.getName());
            count++;
        }
        if (course.getChapterUnit() != null) {
            tblCourse.setChapterUnit(course.getChapterUnit());
            count++;
        }
        if (course.getImg() != null) {
            tblCourse.setImg(course.getImg());
            count++;
        }
        if (course.getIntroduction() != null) {
            tblCourse.setIntroduction(course.getIntroduction());
            count++;
        }
        if (course.getCourseMode() != null) {
            tblCourse.setCourseMode(course.getCourseMode());
            count++;
        }
        if (course.getCourseOpener() != null) {
            tblCourse.setCourseOpener(course.getCourseOpener());
            count++;
        }
        if (course.getMeetCourseState() != null) {
            tblCourse.setMeetCourseState(course.getMeetCourseState());
            count++;
        }
        if (course.getMyuniCourseId() != null) {
            tblCourse.setMyuniCourseId(course.getMyuniCourseId());
            count++;
        }
        if (course.getSchoolId() != null) {
            tblCourse.setSchoolId(course.getSchoolId());
            count++;
        }
        if (course.getSchoolName() != null) {
            tblCourse.setSchoolName(course.getSchoolName());
            count++;
        }
        if (course.getState() != null) {
            tblCourse.setState(course.getState());
            count++;
        }
        if (course.getType() != null) {
            tblCourse.setType(course.getType());
            count++;
        }
        if (course.getUserId() != null) {
            tblCourse.setMajorSpeaker(course.getUserId());
            count++;
        }
        if (course.getUserName() != null) {
            tblCourse.setTeacherName(course.getUserName());
            count++;
        }
        if (course.getCourseCategory() != null) {
            tblCourse.setCourseCategory(course.getCourseCategory());
            count++;
        }
        if (course.getCredit() != null) {// 学分
            tblCourse.setCredit(course.getCredit());
            count++;
        }
        if (course.getCreditPrice() != null) {
            tblCourse.setCreditPrice(course.getCreditPrice());
            count++;
        }
        if (course.getPeriod() != null) {// 总学时
            tblCourse.setCourseTime(course.getPeriod());
            count++;
        }
        /*
         * if (course.getMeetCoursePeriod()!=null) {//见面课学时
         * tblCourse.setMeetCourseTime(course.getMeetCoursePeriod()); count++; }
         */
        if (course.getCourseType() != null) {
            tblCourse.setCourseType(course.getCourseType());
            count++;
        }
        if (course.getTurnType() != null) {
            tblCourse.setTurnType(course.getTurnType());
            count++;
        }
        if (course.getDeleteStatus() != null) {
            tblCourse.setDeleteStatus(course.getDeleteStatus());
            count++;
        }
        return count;
    }

    private int fillCcCourse(final CourseDto course, final CcCourse ccCourse) {
        int count = 0;
        if (course.getIsJumpChapter() != null) {
            ccCourse.setIsJumpChapter(course.getIsJumpChapter());
            count++;
        }
        if (course.getLimitDay() != null) {
            ccCourse.setLimitDay(course.getLimitDay());
            count++;
        }
        if (course.getStudyHour() != null) {
            ccCourse.setStudyHour(course.getStudyHour());
            count++;
        }
        if (course.getReleaseStatus() != null) {
            ccCourse.setReleaseStatus(course.getReleaseStatus());
            count++;
        }
        if (StringUtils.isNotEmpty(course.getTags())) {
            ccCourse.setCourseTag(course.getTags());
            count++;
        }

        return count;
    }

    @Override
    public Long getLinkCourseId(long courseId) {
        String linkId = this.getByField(courseId, "linkCourseId");
        if (StringUtils.isNotBlank(linkId))
            return NumberUtils.toLong(linkId);
        return null;
    }

    @Override
    public Long getByLinkId(final long linkCourseId) {
        final AtomicLong al = new AtomicLong();
        final String key = JedisHelper.key("cc:course:link", linkCourseId);
        jedisExecutor.execute( new Handler() {
            @Override
            public void handle(Jedis jedis) {
                String courseIdStr = jedis.get(key);
                if (StringUtils.isNotBlank(courseIdStr))
                    al.set(NumberUtils.toLong(courseIdStr));
                else {
                    Long courseId = tblCourseMapper.getCourseId(linkCourseId);
                    if (courseId != null) {
                        al.set(courseId);
                        jedis.set(key, courseId.toString());
                    }
                }
            }
        });
        if (al.get() != 0)
            return al.get();
        return null;
    }

    @Override
    public String getCourseBackground(long courseId) {
        return this.getByField(courseId, "courseBackground");
    }

    @Override
    public String getCourseTarget(long courseId) {
        return this.getByField(courseId, "courseTarget");
    }

    @Override
    public String getCourseIntroduction(long courseId) {
        return this.getByField(courseId, "introduction");
    }

    @Override
    public String getCourseImage(long courseId) {
        return this.getByField(courseId, "img");
    }

    @Override
    public Long getMyuniCourseId(long courseId) {
        String myuniCourseId = this.getByField(courseId, "myuniCourseId");
        if (StringUtils.isNotBlank(myuniCourseId))
            return NumberUtils.toLong(myuniCourseId);
        return null;
    }

    @Override
    public Integer getCourseMode(long courseId) {
        String courseMode = this.getByField(courseId, "courseMode");
        if (StringUtils.isNotBlank(courseMode))
            return NumberUtils.toInt(courseMode);
        return null;
    }

    @Override
    public Map<String, String> getStudyDays(long courseId) {
        Map<String, String> map = new HashMap<String, String>();
        String limitDay = this.getByField(courseId, "limitDay");
        if (StringUtils.isNotBlank(limitDay)) {
            map.put("reviewOrExamDays", limitDay);
        }
        // 课程计划中所有的学习时间
        Integer courseStudyDays = chapterService.chapterStudyDays(courseId);
        if (courseStudyDays != null) {
            map.put("courseStudyDays", courseStudyDays.toString());
        }
        return map;
    }

    @Override
    public String getByField(final long courseId, final String field) {
        Assert.notNull(field, "字段名不能为空!");
        final String key = RedisKeyHelper.courseKey(courseId);
        final StringBuffer sb = new StringBuffer();
        jedisExecutor.execute( new Handler() {
            @Override
            public void handle(Jedis jedis) {
                if (!jedis.exists(key)) {
                    touchCourse(courseId);
                }
                String value = jedis.hget(key, field);
                if (value != null) {
                    sb.append(value);
                }
            }
        });
        return sb.length() > 0 ? sb.toString() : null;
    }

    @Override
    public CourseDto touchCourse(final long courseId) {
        CourseDto dto = this.getFromDb(courseId);
        if (dto == null || dto.getCourseId() == null)
            return null;
        final Map<String, String> map = BeanHelper.describe(dto);
        if (!CollectionUtils.isEmpty(map)) {
            jedisExecutor.execute( new Handler() {
                @Override
                public void handle(Jedis jedis) {
                    jedis.hmset(RedisKeyHelper.courseKey(courseId), map);
                }
            });
        }
        return dto;
    }

    @Override
    public String getCourseName(long courseId) {
        return this.getByField(courseId, "name");
    }

    @Override
    public long updateCourseVideoTotalRedis(final long courseId) {
        List<Integer> chapterIds = chapterService.listChapterId(courseId);
        if (CollectionUtils.isEmpty(chapterIds))
            return 0;
        final int videoTotal = lessonService.countVideos(chapterIds)
                + lessonVideoService.countVideos(chapterIds);
        jedisExecutor.execute( new Handler() {
            @Override
            public void handle(Jedis jedis) {
                jedis.hset(RedisKeyHelper.courseKey(courseId), "videoTotal", String.valueOf(videoTotal));
            }
        });
        return videoTotal;
    }

    @Override
    public ScoreAssessRuleDto queryScoreAssessRule(long onlineCourseId) {
        ScoreAssessRule assessRule = tblCourseMapper.queryScoreAssessRule(onlineCourseId);
        ScoreAssessRuleDto dto = null;
        if (assessRule != null) {
            dto = new ScoreAssessRuleDto();
            dto.setBbsScore(assessRule.getBbsScore());
            dto.setCourseId(assessRule.getCourseId());
            dto.setTotalScore(assessRule.getTotalScore());
            dto.setFinalExamScoreShare(assessRule.getFinalExamScoreShare());
            dto.setId(assessRule.getId());
            dto.setMeetCourseScoreShare(assessRule.getMeetCourseScoreShare());
            dto.setOnlineScoreShare(assessRule.getOnlineScoreShare());
            dto.setPostCount(assessRule.getPostCount());
            dto.setReturnPostCount(assessRule.getReturnPostCount());
            dto.setPostScore(assessRule.getPostScore());
            dto.setReturnPostScore(assessRule.getReturnPostScore());
            dto.setIsAddScore(assessRule.getIsAddScore());
            dto.setTeacherGardScore(assessRule.getTeacherGardScore());
            dto.setPostNum(assessRule.getPostNum());
            dto.setReturnPostNum(assessRule.getReturnPostNum());
        }
        return dto;
    }

    @Override
    public void updateCourseState(long courseId, Integer state, long userId) {
        RemoteLogHelper.log(LogModule.COURSE_UPDATE.getCode(), userId, "[开始]更新课程状态({})", courseId);
        tblCourseMapper.updateCourseState(courseId, state);
        // 更新课程缓存
        touchCourse(courseId);
        RemoteLogHelper.log(LogModule.COURSE_UPDATE.getCode(), userId, "[完成]更新课程状态({})", courseId);
    }

    @Override
    public List<TblCourse> findCourseByCourseIds(List<Long> courseIds) {
        String ids = "";
        for (Long courseId : courseIds) {
            ids += courseId + ",";
        }
        ids = ids.substring(0, ids.length() - 1);
        return tblCourseMapper.findCourseByCourseIds(ids);
    }

    @Override
    public List<CourseStatus> findCoursesStatus(List<Long> courseIds) {

        List<CourseStatus> courseStatus = tblCourseMapper.findCoursesStatus(courseIds);
        if (courseStatus != null && courseStatus.size() > 0) {
            for (CourseStatus courseStatus2 : courseStatus) {
                courseStatus2.setSecondStatus(courseStatus2.getSecondStatus() != 3 ? 0 : 1);
            }
        }
        return courseStatus;
    }
    
    

    @Override
    public List<Long> findCourseIdFamilysByCourseId(Long courseId) {
        if (courseId == null)
            return null;
        return tblCourseMapper.findCourseIdFamilysByCourseId(courseId);
    }

    @Override
    public Long findRootCourseIdByCourseId(Long courseId) {
        if (courseId == null)
            return null;
        return tblCourseMapper.findRootCourseIdByCourseId(courseId);
    }

    @Override
    public List<CourseDto> userCourseList(long userId, Integer type) {
        // 接口调整带缓存
        List<CourseDto> list = this.getRedisCourseListData(userId);

        if (CollectionUtils.isEmpty(list)) {
            list = this.setRedisCourseDtoList(userId, type);
        }
        return list;
    }

    @Override
    public int queryVideoCount(long courseId) {

        return tblCourseMapper.queryVideoCount(courseId);
    }

    @Override
    public int findCourseStepStatCount(Long courseId) {
        return tblCourseMapper.findCourseStepStatCount(courseId);
    }

    @Override
    public List<TblCourse> getCourseIntroductionAndMovieClipsInfo(List<Long> courseIds) {
        return tblCourseMapper.getCourseIntroductionAndMovieClipsInfo(courseIds);
    }

    @Override
    public Map<String, String> queryCourseExtentPropByPropNameList(long courseId, List<String> propList) {
        Map<String, String> map = Maps.newHashMap();

        for (String tempField : propList) {
            map.put(tempField, getByField(courseId, tempField));
        }
        return map;
    }

    @Override
    public void removeCourseChecheByCourseId(final Long courseId) {
        jedisExecutor.execute(new Handler() {
            
            @Override
            public void handle(Jedis jedis) {
                jedis.del(RedisKeyHelper.courseKey(courseId));
                
            }
        });
      

    }

    @Override
    public int queryCourseCount(Integer schoolId, String name, Integer courseType, Integer courseStatus) {
        Example example = new Example(TblCourse.class);
        Criteria createCriteria = example.createCriteria();
        createCriteria.andEqualTo("courseOpener", 2);
        createCriteria.andEqualTo("schoolId", schoolId);
        createCriteria.andEqualTo("isDeleted", 0);
        if (!org.apache.commons.lang.StringUtils.isBlank(name)) {
            createCriteria.andLike("name", "%" + name.trim() + "%");
        }
        if (courseType != null) {
            if (courseType == 3) {// 私有云
                createCriteria.andEqualTo("turnType", 1);
            } else {
                createCriteria.andEqualTo("type", courseType);
            }
        }
        if (courseStatus != null) {
            createCriteria.andEqualTo("state", courseStatus);
        } else {
            createCriteria.andIsNull("state");
        }
        return tblCourseMapper.selectCountByExample(example);

    }

    @Override
    public int queryCourseCount(String name, Integer courseType, Integer schoolId) {
        Example example = new Example(TblCourse.class);
        Criteria createCriteria = example.createCriteria();
        createCriteria.andEqualTo("courseOpener", 2);
        createCriteria.andEqualTo("schoolId", schoolId);
        createCriteria.andEqualTo("isDeleted", 0);
        if (!org.apache.commons.lang.StringUtils.isBlank(name)) {
            createCriteria.andLike("name", "%" + name.trim() + "%");
        }
        if (courseType != null) {
            if (courseType.equals(3)) {// 私有云
                createCriteria.andEqualTo("turnType", 1);
            } else {// 进阶试 微课程

                createCriteria.andEqualTo("type", courseType);
            }

        }
        return tblCourseMapper.selectCountByExample(example);

    }

    @Override
    public List<CourseDto> findCourseDtoByList(List<Long> courseIdList) {

        List<CourseDto> courseDtos = Lists.newArrayList();
        CourseDto courseDto = null;
        for (Long courseId : courseIdList) {
            courseDto = get(courseId);
            if (courseDto != null) {
                courseDtos.add(courseDto);
            }
        }
        return courseDtos;
    }

    @Override
    public List<Long> queryCourseIds(Integer schoolId, String name, Integer courseType, Integer courseStatus,
            int offset, int limit) {
        Example example = new Example(TblCourse.class);
        Criteria createCriteria = example.createCriteria();
        createCriteria.andEqualTo("courseOpener", 2);
        createCriteria.andEqualTo("schoolId", schoolId);
        createCriteria.andEqualTo("isDeleted", 0);
        if (!org.apache.commons.lang.StringUtils.isBlank(name)) {
            createCriteria.andLike("name", "%" + name.trim() + "%");
        }
        if (courseType != null) {
            if (courseType == 3) {// 私有云
                createCriteria.andEqualTo("turnType", 1);
            } else {
                createCriteria.andEqualTo("type", courseType);
            }
        }
        if (courseStatus != null) {
            createCriteria.andEqualTo("state", courseStatus);
        } else {
            createCriteria.andIsNull("state");
        }

        List<TblCourse> coursess = tblCourseMapper.selectByExampleAndRowBounds(example, new RowBounds(offset,
                limit));
        List<Long> integers = Lists.newArrayList();
        for (TblCourse tblCourse : coursess) {
            integers.add(tblCourse.getCourseId());
        }
        return integers;
    }

    @Override
    public List<Long> queryCourseIds(String name, Integer courseType, Integer schoolId, int offset, int limit) {
        Example example = new Example(TblCourse.class);
        Criteria createCriteria = example.createCriteria();
        createCriteria.andEqualTo("courseOpener", 2);
        createCriteria.andEqualTo("schoolId", schoolId);
        createCriteria.andEqualTo("isDeleted", 0);
        if (!org.apache.commons.lang.StringUtils.isBlank(name)) {
            createCriteria.andLike("name", "%" + name.trim() + "%");
        }
        if (courseType != null) {
            if (courseType.equals(3)) {// 私有云
                createCriteria.andEqualTo("turnType", 1);
            } else {// 进阶试 微课程
                createCriteria.andEqualTo("type", courseType);
            }

        }
        PageHelper.startPage(offset, limit);
        List<TblCourse> coursess = tblCourseMapper.selectByExample(example);
        PageInfo<TblCourse> info = new PageInfo<TblCourse>(coursess);

        List<Long> integers = Lists.newArrayList();
        for (TblCourse tblCourse : info.getList()) {
            integers.add(tblCourse.getCourseId());
        }
        return integers;

    }

    @Override
    public List<CourseDto> queryCourseInfo(List<Long> courseIds) {
        List<CourseDto> courseDtos = Lists.newArrayListWithCapacity(courseIds.size());
        CourseDto courseDto = null;
        for (Long courseId : courseIds) {
            courseDto = get(courseId);
            if (courseDto != null) {
                courseDtos.add(courseDto);
            }

        }

        return courseDtos;
    }

    // -----------------------------------------------------------------缓存------------------------------------------------------------------------

    /**
     * 从数据库读取数据
     * 
     * @author Rain
     * @time 2016年11月15日-上午9:47:00
     * @param userId
     * @param type
     * @return
     */
    public List<CourseDto> loadCourseList(long userId, Integer type) {
        List<TblCourse> TblCourseList = tblCourseMapper.userCourseList(userId, type);
        if (CollectionUtils.isEmpty(TblCourseList)) {
            return null;
        } else {
            List<CourseDto> courseList = new ArrayList<CourseDto>();
            for (TblCourse tblCourse : TblCourseList) {
                if (tblCourse != null) {
                	tblCourse.setType(type);
                    CourseDto course = new CourseDto();
                    fillCourse(course, tblCourse);
                    courseList.add(course);
                }
            }
            return courseList;
        }
    }

    /**
     * 设置CourseDtoList缓存
     * 
     * @author Rain
     * @time 2016年11月15日-上午9:47:16
     * @param userId
     * @param type
     * @return
     */
    public List<CourseDto> setRedisCourseDtoList(final long userId, final Integer type) {
        List<CourseDto> list = this.loadCourseList(userId, type);

        if (CollectionUtils.isEmpty(list)) {
            return null;
        }

        // 存value到缓存
        for (CourseDto course : list) {

            final CourseDto courseDto = course;

            jedisExecutor.execute( new Handler() {
                @Override
                public void handle(Jedis jedis) {
                    String key = RedisKeyHelper.getCourseKey(courseDto.getCourseId());
                    jedis.hmset(key, BeanHelper.describe(courseDto));
                    jedis.expire(key, RedisKeyHelper.DEFAULT_EXPIRE);
                }
            });

            // 新增缓存set列表
            this.addSetRedisCourseIds(courseDto.getCourseId().toString(), userId);
        }

        return list;
    }

    /**
     * 存keys
     * 
     * @author Rain
     * @time 2016年11月15日-上午9:58:48
     * @param keys
     * @param userId
     */
    public void addSetRedisCourseIds(final String courseId, final Long userId) {
        // 存key到缓存
        jedisExecutor.execute( new Handler() {
            @Override
            public void handle(Jedis jedis) {
                jedis.sadd(RedisKeyHelper.getCourseIdKeys(userId), courseId); // 将课程id存到set集合中
                jedis.expire(RedisKeyHelper.getCourseIdKeys(userId), RedisKeyHelper.DEFAULT_EXPIRE);
            }
        });
    }

    /**
     * 从redis中获取Course课程列表
     * 
     * @author Rain
     * @time 2016年11月15日-上午10:00:56
     * @param userId
     * @return
     */
    public List<CourseDto> getRedisCourseListData(final long userId) {

        List<CourseDto> courseOpenDtoList = new ArrayList<CourseDto>();

        Set<String> courseIds = this.getRedisCourseIdsData(userId);

        if (CollectionUtils.isEmpty(courseIds)) {
            return null;
        }

        for (String courseId : courseIds) {

            CourseDto courseOpenDto = this.findBycourseId(Long.parseLong(courseId));

            if (null == courseOpenDto) {
                continue;
            }

            courseOpenDtoList.add(courseOpenDto);
        }

        return courseOpenDtoList;
    }

    /**
     * 获取课程redis中keys
     * 
     * @author Rain
     * @time 2016年11月15日-上午10:00:40
     * @param userId
     * @return
     */
    public Set<String> getRedisCourseIdsData(final long userId) {
        final Set<String> courseIds = new HashSet<String>();
        jedisExecutor.execute( new Handler() {
            @Override
            public void handle(Jedis jedis) {
                String key = RedisKeyHelper.getCourseIdKeys(userId);
                if (jedis.exists(key)) {

                    // 如果Key存在，将信息转换为课程DTO
                    Set<String> set = jedis.smembers(key);

                    if (!CollectionUtils.isEmpty(set)) {
                        courseIds.addAll(set);
                    }
                }
            }
        });
        return courseIds != null ? courseIds : null;
    }

    /**
     * 存值(Course)对象到redis
     * 
     * @author Rain
     * @time 2016年11月15日-上午10:30:00
     * @param courseId
     * @return
     */
    public CourseDto setRedisCourseData(final long courseId) {
        CourseDto course = this.getFromDb(courseId);

        if (null == course) {
            return null;
        }

        final Map<String, String> map = BeanHelper.describe(course);
        if (!CollectionUtils.isEmpty(map)) {
            jedisExecutor.execute( new Handler() {
                @Override
                public void handle(Jedis jedis) {
                    jedis.hmset(RedisKeyHelper.getCourseKey(courseId), map);
                    jedis.expire(RedisKeyHelper.getCourseKey(courseId), RedisKeyHelper.DEFAULT_EXPIRE);
                }
            });
        }

        return course;
    }

    /**
     * 获取redis中的数据 (Course)
     * 
     * @author Rain
     * @time 2016年11月15日-上午10:30:42
     * @param courseId
     * @return
     */
    public CourseDto getRedisCourseDtoData(final long courseId) {
        final CourseDto courseOpenDto = new CourseDto();
        jedisExecutor.execute( new Handler() {
            @Override
            public void handle(Jedis jedis) {
                CourseDto dto = null;
                String key = RedisKeyHelper.getCourseKey(courseId);
                if (jedis.exists(key)) {
                    // 如果Key存在，将信息转换为课程DTO
                    Map<String, String> map = jedis.hgetAll(key);
                    if (!CollectionUtils.isEmpty(map) && map.get("courseId") != null) {
                        dto = BeanHelper.transTo(map, CourseDto.class);
                    }
                }
                if (dto != null && dto.getCourseId() != null) {
                    BeanHelper.copyProperties(dto, courseOpenDto);
                }
            }
        });
        return courseOpenDto.getCourseId() != null ? courseOpenDto : null;
    }

    /**
     * 清除课程缓存
     * 
     * @author Rain
     * @time 2016年9月13日-下午12:15:22
     * @param courseId
     */
    private void removeCourseDtoCache(final long courseId) {
        jedisExecutor.execute( new Handler() {
            @Override
            public void handle(Jedis jedis) {
                jedis.del(RedisKeyHelper.getCourseKey(courseId));
            }
        });
    }

    /**
     * 清楚缓存set集合中 指定用户下的 指定的课程名称缓存
     * 
     * @author Rain
     * @time 2016年11月25日-下午1:55:32
     * @param userId 指定用户
     * @param courseId 旗下的课程
     */
    private void removeCacheCourseDtoKeys(final long userId, final String courseId) {
        jedisExecutor.execute( new Handler() {
            @Override
            public void handle(Jedis jedis) {
                jedis.srem(RedisKeyHelper.getCourseIdKeys(userId), courseId);
            }
        });
    }

    /**
     * 获取课程对象
     * 
     * @author Rain
     * @time 2016年11月25日-下午6:38:24
     * @param courseId
     * @return
     */
    public CourseDto findBycourseId(final long courseId) {
        CourseDto course = this.getRedisCourseDtoData(courseId);

        if (null == course) {
            course = this.setRedisCourseData(courseId);
        }

        return course;
    }

    @Override
    public int queryVideoCountForMincourse(long courseId) {
        return tblCourseMapper.queryVideoCountForMincourse(courseId);
    }

    @Override
    public void updateCourseBackground(String content, final long courseId, long userId) {
        CourseDto courseDto = new CourseDto();
        courseDto.setCourseId(courseId);
        courseDto.setCourseBackground(content);
        update(courseDto, userId);//更新课程信息
        //更新第一步 的几个小步的状态
        Example example = new Example(FirstStepStat.class);
        Criteria createCriteria = example.createCriteria();
        createCriteria.andEqualTo("courseId", courseId);
        FirstStepStat firstStepStat = new FirstStepStat();
        firstStepStat.setBackgroundStat(1);//更新课程背景的状态
        firstStepStatMapper.updateByExampleSelective(firstStepStat, example);
        
        jedisExecutor.execute( new Handler() {//清除缓存 以便下次重新读取数据库
            @Override
            public void handle(Jedis jedis) {
               jedis.del("FIRST_STEP"+courseId);

            }
        });

    }

    @Override
    public void updateCourseTarget(String content, final long courseId, long userId) {
       CourseDto courseDto=new CourseDto();
       courseDto.setCourseId(courseId);
       courseDto.setCourseTarget(content);
       update(courseDto, userId);//更新课程目标
       //更新第一步 的几个小步的状态
       Example example = new Example(FirstStepStat.class);
       Criteria createCriteria = example.createCriteria();
       createCriteria.andEqualTo("courseId", courseId);
       FirstStepStat firstStepStat = new FirstStepStat();
       firstStepStat.setTagetStat(1);//更新课程目标的状态
       firstStepStatMapper.updateByExampleSelective(firstStepStat, example);
       
       jedisExecutor.execute( new Handler() {//清除缓存 以便下次重新读取数据库
           @Override
           public void handle(Jedis jedis) {
              jedis.del("FIRST_STEP"+courseId);

           }
       });

        
    }

    @Override
    public void updateCourseDesignPrinciple(String content, final long courseId, long userId) {
       CourseDto courseDto=new CourseDto();
       courseDto.setCourseId(courseId);
       courseDto.setIntroduction(content);
       update(courseDto, userId);
       //更新第一步 的几个小步的状态
       Example example = new Example(FirstStepStat.class);
       Criteria createCriteria = example.createCriteria();
       createCriteria.andEqualTo("courseId", courseId);
       FirstStepStat firstStepStat = new FirstStepStat();
       firstStepStat.setIntroduceStat(1);//更新课程设计原则
       firstStepStatMapper.updateByExampleSelective(firstStepStat, example);
       
       jedisExecutor.execute( new Handler() {//清除缓存 以便下次重新读取数据库
           @Override
           public void handle(Jedis jedis) {
              jedis.del("FIRST_STEP"+courseId);

           }
       });
        
    }

    @Override
    public void updateBaseInfo(CourseBaseInfoDto courseBaseInfoDto, long userId,final long courseId) {
        if (log.isDebugEnabled()) {
            log.debug("更新课程基本信息为:{}",courseBaseInfoDto);
        }
        update(BeanHelper.transTo(courseBaseInfoDto, CourseDto.class), userId);//更新课程信息
        //更新第一步 的几个小步的状态
        Example example = new Example(FirstStepStat.class);
        Criteria createCriteria = example.createCriteria();
        createCriteria.andEqualTo("courseId", courseId);
        FirstStepStat firstStepStat = new FirstStepStat();
        firstStepStat.setBaseInfoStat(courseBaseInfoDto.getIsBasicInfoComplete());//更新课程设计原则
        firstStepStatMapper.updateByExampleSelective(firstStepStat, example);
        
        jedisExecutor.execute( new Handler() {//清除缓存 以便下次重新读取数据库
            @Override
            public void handle(Jedis jedis) {
               jedis.del("FIRST_STEP"+courseId);
            }
        });
        
        
        
    }

    @Override
    public void updateCourseModel(int courseModel, final long courseId, long userId) {
        
        CourseDto temp=get(courseId);
        if (log.isDebugEnabled()) {
            log.debug("当前的课程模式为:{}",temp.getCourseMode());
        }
      if (MIX_MODEL.equals(courseModel)&&temp.getCourseMode().equals(ONLINE_MODEL)) {//原来是在线式变为混合式  
          CourseDto courseDto=new CourseDto();
          courseDto.setCourseId(courseId);
          courseDto.setCourseMode(courseModel);
          update(courseDto, userId);//更新
          checkFisrtStepCompStat(courseId, temp,courseModel);
         
        
    }
    if (ONLINE_MODEL.equals(courseModel)&&temp.getCourseMode().equals(MIX_MODEL)) {//原来是混合式变变为纯在线
        
        CourseDto courseDto=new CourseDto();
        courseDto.setCourseId(courseId);
        if (temp.getMeetCoursePeriod()!=null) {//如果已近存在见面课学时(将其更改为0)
            courseDto.setMeetCoursePeriod(0);
        }
        courseDto.setPeriod(temp.getOnlineCoursePeriod());//纯在线课程 总学时=在线学时
        courseDto.setCourseMode(courseModel);
        update(courseDto, userId);//更新
        checkFisrtStepCompStat(courseId, temp,courseModel);
    }
    jedisExecutor.execute( new Handler() {//清除缓存 以便下次重新读取数据库
        @Override
        public void handle(Jedis jedis) {
           jedis.del("FIRST_STEP"+courseId);
        }
    });
        
    }

    private void checkFisrtStepCompStat(final long courseId, CourseDto temp,int courseModel) {
        if (org.springframework.util.StringUtils.isEmpty(temp.getName())) {//课程名为空
          //更新第一步的基本信息为不完整
            updateBaseInfoStatus(courseId,INCOMPLETE);
            //更新第一步为不完整
            courseBuildService.updateCourseStepStat(courseId, COURSE_FIRST_STEP, INCOMPLETE);
            return; 
        }
        if (org.springframework.util.StringUtils.isEmpty(temp.getSchoolName())) {//所属学校
            //更新第一步的基本信息为不完整
            updateBaseInfoStatus(courseId,INCOMPLETE);
            //更新第一步为不完整
            courseBuildService.updateCourseStepStat(courseId, COURSE_FIRST_STEP, INCOMPLETE);
            return; 
        }
        if (org.springframework.util.StringUtils.isEmpty(temp.getCourseTeacher())) {//学术总策划
            //更新第一步的基本信息为不完整
            updateBaseInfoStatus(courseId,INCOMPLETE);
            //更新第一步为不完整
            courseBuildService.updateCourseStepStat(courseId, COURSE_FIRST_STEP, INCOMPLETE);
            return; 
        }
        if (temp.getCourseCategory()==null) {//没有课程分类
          //更新第一步的基本信息为不完整
            updateBaseInfoStatus(courseId,INCOMPLETE);
            //更新第一步为不完整
            courseBuildService.updateCourseStepStat(courseId, COURSE_FIRST_STEP, INCOMPLETE);
            return; 
        }
        //学科类别是否存在
        List<CourseCategoryDto>  list = categoryService.listByCourse(courseId);
        if (CollectionUtils.isEmpty(list)) {
          //更新第一步的基本信息为不完整
            updateBaseInfoStatus(courseId,INCOMPLETE);
            //更新第一步为不完整
            courseBuildService.updateCourseStepStat(courseId, COURSE_FIRST_STEP, INCOMPLETE);
            return; 
        }
        if (temp.getOnlineCoursePeriod()==null) {//在线学时为空
            //更新第一步的基本信息为不完整
            updateBaseInfoStatus(courseId,INCOMPLETE);
            //更新第一步为不完整
            courseBuildService.updateCourseStepStat(courseId, COURSE_FIRST_STEP, INCOMPLETE);
            return; 
        }
        System.out.println("是否进入"+MIX_MODEL.equals(courseModel));
        if (MIX_MODEL.equals(courseModel)) {
            if (temp.getMeetCoursePeriod()==null||temp.getMeetCoursePeriod()==0) {//如果当前是混合式 而见面课学时为0或者为null则认为不通过
                //更新第一步的基本信息为不完整
                updateBaseInfoStatus(courseId,INCOMPLETE);
                //更新第一步为不完整
                courseBuildService.updateCourseStepStat(courseId, COURSE_FIRST_STEP, INCOMPLETE);
                return;
            }
        }
        
        updateBaseInfoStatus(courseId,COMPLETE);
        //更新第一步为不完整
        courseBuildService.updateCourseStepStat(courseId, COURSE_FIRST_STEP, COMPLETE);
    }

    private void updateBaseInfoStatus(final long courseId,Integer status) {
        Example example = new Example(FirstStepStat.class);
          Criteria createCriteria = example.createCriteria();
          createCriteria.andEqualTo("courseId", courseId);
          FirstStepStat firstStepStat = new FirstStepStat();
          firstStepStat.setBaseInfoStat(status);//更新课程基本信息
          int tempCount=firstStepStatMapper.updateByExampleSelective(firstStepStat, example);
          if (log.isDebugEnabled()) {
            log.debug("更新第一步的课程基本信息变为不完整影响的行数:{}",tempCount);
        }
    }

    @Override
    public Integer queryCourseTypeByCourseId(long courseId) {
          CourseDto courseDto = get(courseId);
          if (courseDto!=null) {
             
              if (courseDto.getType()==1&&courseDto.getTurnType()==0) {//进阶
                  return 1;               
            }
              if (courseDto.getType()==1&&courseDto.getTurnType()==1) {//校内
                  return 3;               
            }
              if (courseDto.getType()==2) {//微课程
                  return 2;
                
            }
              if (courseDto.getType()==4) {//海外
                  return 4;                
              }
        }
        return null;
    }

    @Override
    public List<Object> getChapterLessonInfo(Jedis jedis, Set<String> chapterIds, Set<String> lessonIds,
            Set<String> lvIds, String[] chapterFields, String[] lessonFields, String[] lessonVideoFields) {

        Pipeline pip = jedis.pipelined();
        // 获取章数据
        if (!CollectionUtils.isEmpty(chapterIds)){
            for (String chapterId : chapterIds) {
                if (chapterId == null){
                    continue;
                }
                pip.hmget(JedisHelper.key("cc:chapter", chapterId),chapterFields);
            }
        }
        // 获取节数据
        if (!CollectionUtils.isEmpty(lessonIds)){
            for (String lessonId : lessonIds) {
                if (lessonId == null){
                    continue;
                }
                pip.hmget(JedisHelper.key("cc:lesson", lessonId),lessonFields );
            }
        }
        // 获取小节数据
        if (!CollectionUtils.isEmpty(lvIds)){
            for (String lvId : lvIds) {
                pip.hmget(JedisHelper.key("cc:lv", lvId), lessonVideoFields);
            }
        }
        // 提取结果
        List<Object> result = pip.syncAndReturnAll();
        return result;

    }

	@Override
	public List<CourseDto> overseasCourseList(List<Long> courseIds) {
		// 接口调整带缓存 暂时不走缓存
        List<CourseDto> list = this.getRedisOverSeasCourseListData(courseIds);
		/*List<CourseDto> list = new ArrayList<CourseDto>();
		for (Long courseId : courseIds) {
			CourseDto course = this.getFromDb(courseId);
			if (null != course) {
				CourseDto courseOpenDto = new CourseDto();
				BeanHelper.copyProperties(course, courseOpenDto);
				list.add(courseOpenDto);
	        }
		}*/
        return list;
	}

	private List<CourseDto> getRedisOverSeasCourseListData(final List<Long> courseIds) {
		List<CourseDto> courseOpenDtoList = new ArrayList<CourseDto>();

        if (CollectionUtils.isEmpty(courseIds)) {
            return null;
        }

        courseOpenDtoList = getRedisOverSeasCourseData(courseIds);
        
        List<Long> noRedisCourseIds = new ArrayList<Long>();
        
        noRedisCourseIds=courseIds;
        
    	for (CourseDto courseOpen : courseOpenDtoList) {
			if(courseIds.contains(courseOpen.getCourseId())){
				noRedisCourseIds.remove(courseOpen.getCourseId());
			}
		}
        
        
        if(!CollectionUtils.isEmpty(noRedisCourseIds)){
        	for (Long courseId : noRedisCourseIds) {
        		CourseDto courseDto = setRedisCourseData(courseId);
        		if(null != courseDto){
        			courseOpenDtoList.add(courseDto);
        		}
			}
        }

        return courseOpenDtoList;
	}
	
	private List<CourseDto> getRedisOverSeasCourseData(final List<Long> courseIds){
		final List<CourseDto> courseOpenDtoList = new ArrayList<CourseDto>();
		jedisExecutor.execute( new Handler() {
			@Override
			public void handle(Jedis jedis) {

				Pipeline p = jedis.pipelined();

				// 使用管道，从Redis中查询信息
				for (Long courseId : courseIds) {
					p.hgetAll(RedisKeyHelper.getCourseKey(courseId));
				}

				List<Object> list = p.syncAndReturnAll();

				if (!CollectionUtils.isEmpty(list)) {
					for (Object obj : list) {

						if (obj == null) {
							continue;
						}

						@SuppressWarnings("unchecked")
						Map<String, String> hash = (Map<String, String>) obj;
						if (CollectionUtils.isEmpty(hash) || hash.get("courseId") == null) {
							continue;
						}
						CourseDto courseOpenDto = BeanHelper.transTo(hash, CourseDto.class);
						courseOpenDtoList.add(courseOpenDto);

					}
				}
			}
		});
		return courseOpenDtoList;
		
	}

    @Override
    public void syncCacheMainSpeaker(final String speaker, final long courseId, long userId) {
        jedisExecutor.execute(new Handler() {
            @Override
            public void handle(Jedis jedis) {
                List<Integer> lessonIds=lessonService.getlessonIdsByCourseId(courseId);
                List<Integer> lesonVideoIds=lessonVideoService.getIdByCourseId(courseId);
               /* Set<String> lessonIds = jedis.smembers(String.format("cc:course:%d:lessons", courseId));
                Set<String> lvIds = jedis.smembers(String.format("cc:course:%d:lvs", courseId));*/
                if (log.isDebugEnabled()) {
                    log.debug("查询到课程{}下节ids为{}",courseId,lessonIds);
                    log.debug("查询到课程{}下小节ids为{}",courseId,lesonVideoIds);
                }
                Pipeline pipelined = jedis.pipelined();
                if (!CollectionUtils.isEmpty(lessonIds)) {
                    for (Integer lessonId : lessonIds) {
                        pipelined.hset(String.format("cc:lesson:%d",lessonId), "speaker", speaker);
                    }
                   /* for (String lessonIdString : lessonIds) {
                       
                    }*/
                }
                if (!CollectionUtils.isEmpty(lesonVideoIds)) {
                   /* for (String lvString : lvIds) {
                      
                    }*/
                    for (Integer lessonVideoId : lesonVideoIds) {
                        pipelined.hset(String.format("cc:lv:%d", lessonVideoId),"speaker", speaker);
                    }
                    
                }
                pipelined.sync();
            }
        });
        
    }

    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
}
